package com.bgds.sys.task;

import cn.hutool.core.util.ObjectUtil;
import com.bgds.sys.api.factory.MsgKeyFactory;
import com.bgds.sys.common.constant.BizConstant;
import com.bgds.sys.common.enums.AlarmLogAlarmLevelEnum;
import com.bgds.sys.influx.service.InfluxService;
import com.bgds.sys.module.entity.AlarmLog;
import com.bgds.sys.module.entity.DeviceDynamicAttr;
import com.bgds.sys.module.service.IAlarmLogService;
import com.bgds.sys.module.service.IDeviceDynamicAttrService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @author Smiling
 * @description: 监测点报警任务
 * @date 2021/5/27  22:18
 */
@Slf4j
@Component
public class AlarmJob implements Job {

    @Autowired
    private IDeviceDynamicAttrService iDeviceDynamicAttrService;
    @Autowired
    private InfluxService influxService;
    @Autowired
    private IAlarmLogService iAlarmLogService;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        //获取需要报警的监测点
        List<DeviceDynamicAttr> attrList = iDeviceDynamicAttrService.listByAlarmFlag();
        //插入日志的集合
        List<AlarmLog> alarmLogs = new ArrayList<>();
        List<AlarmLog> notAlarmLogs = new ArrayList<>();
        //进行阈值报警判断
        attrList.forEach(dynamicAttr -> {
            //判断每个监测点的阈值是否报警
            AlarmLog log = judgeAlarm(dynamicAttr, dynamicAttr.getCurrentValue());
            if (null!=log &&null!=log.getAlarmLevel()) {
                alarmLogs.add(log);
            }else if (null!=log &&null==log.getAlarmLevel()){
                notAlarmLogs.add(log);
            }
        });

        Map<String,List<AlarmLog>> map  =new HashMap();
        map.put(BizConstant.ALARM,alarmLogs);
        map.put(BizConstant.NOT_ALARM,notAlarmLogs);

        iAlarmLogService.saveAlarmLogs(map);
    }

    private AlarmLog judgeAlarm(DeviceDynamicAttr attr, Object value) {
        AlarmLog log = null;

        if (ObjectUtil.isEmpty(value)||null== attr.getJudgeType()) {
            return null;
        }

        Float f = Float.valueOf(value.toString());
        //如果是差值类型，就取绝对值
        if (BizConstant.GROUP_CODE_GAP.equalsIgnoreCase(attr.getGroupCode())){
            f= Math.abs(f);
        }

        //判断报警等级
        Integer alarmLevel = getAlarmLevelByJudgeType(attr, f);
        log = createAlarmLog(alarmLevel, attr.getId(), attr.getDeviceCode());
        return log;
    }

    /**
     * 通过设置的方法判断报警等级
     *
     * @param attr
     * @param value
     * @return
     */
    private Integer getAlarmLevelByJudgeType(DeviceDynamicAttr attr, Float value) {
        Integer alarmLevel = null;
        Integer judgeType = attr.getJudgeType();

        //用上限法判断
        if (BizConstant.Upper.equals(judgeType)) {
            if ( value >= attr.getThreeTopLimit()) {
                alarmLevel = BizConstant.ALARM_LEVEL_TREE;
            } else if ( value >= attr.getTwoTopLimit()) {
                alarmLevel = BizConstant.ALARM_LEVEL_TWO;
            } else if (value >=attr.getOneTopLimit()) {
                alarmLevel = BizConstant.ALARM_LEVEL_ONE;
            }
        }
        //用下限法判断
        if (BizConstant.lower.equals(judgeType)) {
            if (value <=attr.getThreeLowLimit()) {
                alarmLevel = BizConstant.ALARM_LEVEL_TREE;
            } else if (value <= attr.getTwoLowLimit()) {
                alarmLevel = BizConstant.ALARM_LEVEL_TWO;
            } else if (value <=attr.getOneLowLimit()) {
                alarmLevel = BizConstant.ALARM_LEVEL_ONE;
            }
        }
        //范围法判断
        if (BizConstant.Range.equals(judgeType)) {
            if ( value >=attr.getThreeTopLimit()||value <= attr.getThreeLowLimit()) {
                alarmLevel = BizConstant.ALARM_LEVEL_TREE;
            } else if ( value >=attr.getTwoTopLimit()||value <= attr.getTwoLowLimit()) {
                alarmLevel = BizConstant.ALARM_LEVEL_TWO;
            } else if (value >= attr.getOneTopLimit()||value <= attr.getOneLowLimit() ) {
                alarmLevel = BizConstant.ALARM_LEVEL_ONE;
            }
        }
        return alarmLevel;
    }

    /**
     * 生成报警日志
     *
     * @param level
     * @param attrId
     * @param deviceCode
     * @return
     */
    private AlarmLog createAlarmLog(Integer level, Long attrId, String deviceCode) {
        AlarmLog alarmLog = new AlarmLog();
        //报警
        if (null!=level){
            alarmLog.setAlarmDate(System.currentTimeMillis());
            alarmLog.setAttrId(attrId);
            alarmLog.setCategory(BizConstant.ALARM_INFO);
            alarmLog.setDeviceCode(deviceCode);
            alarmLog.setStatus(0);
            alarmLog.setAlarmLevel(level);
            alarmLog.setAlarmLevelName(AlarmLogAlarmLevelEnum.getValueByCode(level));
        }else {
            alarmLog.setAttrId(attrId);
            alarmLog.setDeviceCode(deviceCode);
        }
        return alarmLog;
    }


}